/**
 * Axios 请求封装
 * 基于 axios 封装的统一请求模块
 */
import axios from 'axios'
import { ElMessage, ElLoading } from 'element-plus'
import { getToken, removeToken } from '@/utils/storage'

// 创建 axios 实例
const service = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL || '/api',
  timeout: 15000,
  headers: {
    'Content-Type': 'application/json;charset=UTF-8'
  }
})

// 当前正在进行的请求
let loading = null
let requestCount = 0

// 显示加载
function showLoading() {
  if (requestCount === 0) {
    loading = ElLoading.service({
      lock: true,
      text: '加载中...',
      background: 'rgba(0, 0, 0, 0.7)'
    })
  }
  requestCount++
}

// 隐藏加载
function hideLoading() {
  requestCount--
  if (requestCount === 0 && loading) {
    loading.close()
    loading = null
  }
}

// 请求拦截器
service.interceptors.request.use(
  (config) => {
    // 显示加载动画（可以通过 config.hideLoading 控制）
    if (!config.hideLoading) {
      showLoading()
    }
    
    // 添加 token
    const token = getToken()
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
    }
    
    // 请求日志
    console.log('📤 [Request]', {
      url: config.url,
      method: config.method,
      params: config.params,
      data: config.data
    })
    
    return config
  },
  (error) => {
    hideLoading()
    console.error('❌ [Request Error]', error)
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  (response) => {
    hideLoading()
    
    const res = response.data
    
    // 响应日志
    console.log('📥 [Response]', {
      url: response.config.url,
      data: res
    })
    
    // 根据后端约定的 code 判断请求结果
    // 这里假设后端返回格式为 { code, data, message }
    if (res.code === undefined) {
      // 如果没有 code 字段，直接返回数据
      return res
    }
    
    // code === 200 表示成功
    if (res.code === 200 || res.code === 0) {
      return res.data
    }
    
    // token 过期或无效
    if (res.code === 401) {
      ElMessage.error(res.message || '登录已过期，请重新登录')
      removeToken()
      // 跳转到登录页
      window.location.href = '/login'
      return Promise.reject(new Error(res.message || '登录已过期'))
    }
    
    // 其他错误
    ElMessage.error(res.message || '请求失败')
    return Promise.reject(new Error(res.message || '请求失败'))
  },
  (error) => {
    hideLoading()
    
    console.error('❌ [Response Error]', error)
    
    let message = '请求失败'
    
    if (error.response) {
      // 服务器返回了错误状态码
      switch (error.response.status) {
        case 400:
          message = '请求参数错误'
          break
        case 401:
          message = '未授权，请重新登录'
          removeToken()
          window.location.href = '/login'
          break
        case 403:
          message = '拒绝访问'
          break
        case 404:
          message = '请求资源不存在'
          break
        case 500:
          message = '服务器内部错误'
          break
        case 502:
          message = '网关错误'
          break
        case 503:
          message = '服务不可用'
          break
        case 504:
          message = '网关超时'
          break
        default:
          message = `连接错误 ${error.response.status}`
      }
    } else if (error.message) {
      if (error.message.includes('timeout')) {
        message = '请求超时'
      } else if (error.message.includes('Network Error')) {
        message = '网络错误，请检查网络连接'
      }
    }
    
    ElMessage.error(message)
    return Promise.reject(error)
  }
)

/**
 * 封装通用的请求方法
 */
const request = {
  /**
   * GET 请求
   * @param {string} url 请求地址
   * @param {object} params 请求参数
   * @param {object} config 其他配置
   */
  get(url, params = {}, config = {}) {
    return service({
      url,
      method: 'get',
      params,
      ...config
    })
  },
  
  /**
   * POST 请求
   * @param {string} url 请求地址
   * @param {object} data 请求数据
   * @param {object} config 其他配置
   */
  post(url, data = {}, config = {}) {
    return service({
      url,
      method: 'post',
      data,
      ...config
    })
  },
  
  /**
   * PUT 请求
   * @param {string} url 请求地址
   * @param {object} data 请求数据
   * @param {object} config 其他配置
   */
  put(url, data = {}, config = {}) {
    return service({
      url,
      method: 'put',
      data,
      ...config
    })
  },
  
  /**
   * DELETE 请求
   * @param {string} url 请求地址
   * @param {object} params 请求参数
   * @param {object} config 其他配置
   */
  delete(url, params = {}, config = {}) {
    return service({
      url,
      method: 'delete',
      params,
      ...config
    })
  },
  
  /**
   * PATCH 请求
   * @param {string} url 请求地址
   * @param {object} data 请求数据
   * @param {object} config 其他配置
   */
  patch(url, data = {}, config = {}) {
    return service({
      url,
      method: 'patch',
      data,
      ...config
    })
  },
  
  /**
   * 上传文件
   * @param {string} url 请求地址
   * @param {FormData} formData 表单数据
   * @param {function} onProgress 上传进度回调
   */
  upload(url, formData, onProgress) {
    return service({
      url,
      method: 'post',
      data: formData,
      headers: {
        'Content-Type': 'multipart/form-data'
      },
      onUploadProgress: (progressEvent) => {
        if (onProgress) {
          const percentCompleted = Math.round(
            (progressEvent.loaded * 100) / progressEvent.total
          )
          onProgress(percentCompleted)
        }
      }
    })
  },
  
  /**
   * 下载文件
   * @param {string} url 请求地址
   * @param {object} params 请求参数
   * @param {string} filename 文件名
   */
  download(url, params = {}, filename = 'download') {
    return service({
      url,
      method: 'get',
      params,
      responseType: 'blob'
    }).then((data) => {
      const blob = new Blob([data])
      const link = document.createElement('a')
      link.href = URL.createObjectURL(blob)
      link.download = filename
      link.click()
      URL.revokeObjectURL(link.href)
    })
  }
}

export default request
export { service }
